import json
import pickle
import re

from django.contrib.auth import authenticate, login, logout
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.views import View
from rest_framework import mixins
from rest_framework.authtoken.models import Token
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import UpdateModelMixin
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.viewsets import ViewSet, ModelViewSet

from apps.users.models import User
from apps.users.serializers import UserModelSerializer, UserSerializer
from utils.page import PageNum
from rest_framework.permissions import AllowAny, IsAdminUser
from rest_framework_jwt.settings import api_settings

from utils.response import ReturnMsg


class LoginView(APIView):
    permission_classes = [AllowAny]

    def get(self, request):
        return JsonResponse({
            "code": 0,
            "type": "访问成功",
            "message": "",
            "user": str(request.user)
        })

    def post(self, request):
        # 登陆
        try:
            data = json.loads(request.body.decode())
        except:
            return JsonResponse({
                "code": 4000,
                "type": "请求参数非法",
                "message": "参数设置非法"
            },
                json_dumps_params={"ensure_ascii": False})
        username = data.get("username")
        password = data.get("password")
        # 2.校验(整体 + 单个)
        if not all([username, password]):
            return JsonResponse({
                "code": 4000,
                "type": "请求参数非法",
                "message": "缺少必要参数"
            },
                json_dumps_params={"ensure_ascii": False})
        # 修改 USERNAME_FIELD 来影响 authenticate 的查询
        if re.match("^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$", username):
            # 邮箱
            User.USERNAME_FIELD = "email"
        else:
            # account 是用户名
            # 根据用户名从数据库获取 user 对象返回.
            User.USERNAME_FIELD = "username"
        # 3.验证是否能够登录
        user = authenticate(username=username,
                            password=password)

        # 判断是否为空,如果为空,返回
        if user is None:
            return JsonResponse({"code": 4000,
                                 "type": "请求参数非法",
                                 "message": "账户或密码错误"},
                                json_dumps_params={"ensure_ascii": False})

        # 4.状态保持
        # login(request, user)
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)

        # # 5.判断是否记住用户
        # if not remembered:
        #     # 7.如果没有记住: 关闭立刻失效
        #     request.session.set_expiry(0)
        # else:
        #     # 6.如果记住:  设置为两周有效，默认为两周
        #     request.session.set_expiry(None)

        # 8.返回json

        response = JsonResponse({"code": 0,
                                 "type": "访问成功",
                                 "message": "登陆成功",
                                 "token": token,
                                 "superuser": user.is_superuser,
                                 "email": user.email
                                 },
                                json_dumps_params={"ensure_ascii": False})
        # 注册时用户名写入到cookie，有效期15天

        return response

    # def delete(self, request):
    #     # logout(request)
    #     response = JsonResponse(
    #         {"code": 0,
    #          "type": "访问成功",
    #          "message": "退出成功"},
    #         json_dumps_params={"ensure_ascii": False})
    #     return response


class RegisterView(APIView):
    permission_classes = [AllowAny]

    def post(self, request):
        try:
            data = json.loads(request.body.decode())
        except:
            return JsonResponse({
                "code": 4000,
                "type": "请求参数非法",
                "message": "参数设置非法"
            },
                json_dumps_params={"ensure_ascii": False})
        username = data.get('username')
        password = data.get('password')
        password2 = data.get('password2')
        email = data.get('email')

        # 判断参数是否齐全
        if not all([username, password, password2, email]):
            return JsonResponse({
                "code": 4000,
                "type": "请求参数非法",
                "message": "缺少必传参数"
            },
                json_dumps_params={"ensure_ascii": False})
        # 判断用户名是否是5-20个字符
        if not re.match(r'^[a-zA-Z0-9_]{5,20}$', username):
            return JsonResponse({
                "code": 4000,
                "type": "请求参数非法",
                "message": "用户名有误"
            },
                json_dumps_params={"ensure_ascii": False})

        if not re.match('^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$', email):
            return JsonResponse({
                "code": 4000,
                "type": "请求参数非法",
                "message": "邮箱格式有误"},
                json_dumps_params={"ensure_ascii": False})
        # 判断密码是否是5-17个数字
        if not re.match(r'^[a-zA-Z]\w{5,17}$', password):
            return JsonResponse({
                "code": 4000,
                "type": "请求参数非法",
                "message": "密码格式有误"
            },
                json_dumps_params={"ensure_ascii": False})
        # 判断两次密码是否一致
        if password != password2:
            return JsonResponse({
                "code": 4000,
                "type": "请求参数非法",
                "message": "两次密码不一致"},
                json_dumps_params={"ensure_ascii": False})
        # 判断是否勾选用户协议

        try:
            # create_user()方法中封装了set_password()方法加密密码
            user = User.objects.create_user(username=username,
                                            password=password,
                                            email=email)
        except Exception as e:
            return JsonResponse({
                "code": 4000,
                "type": "请求参数非法",
                "message": "注册失败"},
                json_dumps_params={"ensure_ascii": False})

            # 注册时用户名写入到cookie，有效期15天

        # login(request, user)
        jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
        jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER

        payload = jwt_payload_handler(user)
        token = jwt_encode_handler(payload)
        response = JsonResponse({
            "code": 0,
            "type": "访问成功",
            'message': '注册成功，自动登录',
            "token": token,
            "superuser": user.is_superuser,
            "email": user.email
        },
            json_dumps_params={"ensure_ascii": False})
        return response


class UserModelView(ModelViewSet):
    permission_classes = [IsAdminUser, ]  # 全局配置后，不让login验证，直接加空列表就不验证

    def get_queryset(self):
        # if self.request.user.is_superuser:
        return User.objects.all()

    serializer_class = UserModelSerializer

    def create(self, request, *args, **kwargs):
        response = super(UserModelView, self).create(request, args, kwargs)
        return Response(ReturnMsg(data=response.data).dict(), status=response.status_code)

    def retrieve(self, request, *args, **kwargs):
        response = super(UserModelView, self).retrieve(request, args, kwargs)
        return Response(ReturnMsg(data=response.data).dict(), status=response.status_code)

    def update(self, request, *args, **kwargs):
        response = super(UserModelView, self).update(request, args, kwargs)
        return Response(ReturnMsg(data=response.data).dict(), status=response.status_code)

    def destroy(self, request, *args, **kwargs):
        response = super(UserModelView, self).destroy(request, args, kwargs)
        return Response(ReturnMsg().dict(), status=response.status_code)


class UserView(APIView):
    # def get_queryset(self):
    #     user = self.request.user
    #     return User.objects.filter(id=user.id)
    #
    # serializer_class = UserSerializer

    # lookup_field = 'id'

    def get(self, request):
        serializer = UserSerializer(request.user)
        return Response(serializer.data)

    def put(self, request):
        user_dict = request.data
        serializer = UserSerializer(data=user_dict)
        # 3.验证数据，并根据验证结果进行判断
        if serializer.is_valid():

            serializer.save()
            return Response(serializer.data)
        else:
            return Response({'msg': '保存失败'})

